package com.chiyou.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpException;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chiyou.common.indicator.KLineData;
import com.chiyou.common.models.HisData;
import com.chiyou.common.utils.PropertiesUtils;
import com.chiyou.common.utils.RedisUtilStr;
import com.chiyou.common.utils.RedisUtils;
import com.okcoin.rest.future.IFutureRestApi;
import com.okcoin.rest.future.impl.FutureRestApiV1;
import com.okcoin.rest.future.models.Btc;
import com.okcoin.rest.future.models.Contracts;
import com.okcoin.rest.future.models.Holding;
import com.okcoin.rest.future.models.Info;
import com.okcoin.rest.future.models.OkCoinUserInfo;
import com.okcoin.rest.future.models.Position;
import com.okcoin.rest.future.models.Trade;

public class FutureNo1TradingService implements Runnable {
	public static RedisUtilStr redisUtilStr = new RedisUtilStr();
	public void run() {
		try {
			String api_key = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("apikey");
			String secret_key = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("secretkey");
			String url_prex = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/conf.properties").getProperty("urlprex");
			// String tard_type =
			// PropertiesUtils.getInstance(System.getProperty("user.dir") +
			// "/conf/trading.properties").getProperty("tard_type");
			// String current_tard_price =
			// PropertiesUtils.getInstance(System.getProperty("user.dir") +
			// "/conf/trading.properties").getProperty("current_tard_price");
			// String option_status =
			// PropertiesUtils.getInstance(System.getProperty("user.dir") +
			// "/conf/trading.properties").getProperty("option_status");
			// String current_order_id =
			// PropertiesUtils.getInstance(System.getProperty("user.dir") +
			// "/conf/trading.properties").getProperty("current_order_id");
			// String netwok_val =
			// PropertiesUtils.getInstance(System.getProperty("user.dir") +
			// "/conf/trading.properties").getProperty("netwok_val");

//			String tard_type = RedisUtils.getJedis().get("tard_type");
//			String netwok_val = RedisUtils.getJedis().get("netwok_val");
//			String current_tard_price = RedisUtils.getJedis().get("current_tard_price");
//			String option_status = RedisUtils.getJedis().get("option_status");
//			String current_order_id = RedisUtils.getJedis().get("current_order_id");

			String tard_type = ""+ redisUtilStr.get("tard_type");
			String netwok_val = ""+ redisUtilStr.get("netwok_val");
			String current_tard_price = ""+ redisUtilStr.get("current_tard_price");
			String option_status = ""+ redisUtilStr.get("option_status");
			String current_order_id = ""+ redisUtilStr.get("current_order_id");

			/**
			 * get请求无需发送身份认证,通常用于获取行情，市场深度等公共信息
			 */
			IFutureRestApi futureGetV1 = new FutureRestApiV1(url_prex);

			/**
			 * post请求需发送身份认证，获取用户个人相关信息时，需要指定api_key,与secret_key并与参数进行签名，
			 * 此处对构造方法传入api_key与secret_key,在请求用户相关方法时则无需再传入，
			 * 发送post请求之前，程序会做自动加密，生成签名。
			 * 
			 */
			IFutureRestApi futurePostV1 = new FutureRestApiV1(url_prex, api_key, secret_key);

			// 期货交易信息
			String trades = futureGetV1.future_trades("btc_usd", "quarter");
			OkCoinUserInfo okCoinUserInfo = getOkCoinUserInfo(futurePostV1);

			// JSONArray array = JSONArray.parseArray(trades);

			List<Trade> tradeList = net.sf.json.JSONArray.toList(net.sf.json.JSONArray.fromObject(trades), Trade.class);
			double newBuy = 0.0F;
			double newSell = 0.0F;
			for (int i = 0; i < tradeList.size(); i++) {
				Trade trade = tradeList.get(i);
				if (trade.getType().equals("buy") && newBuy != 0) {
					newBuy = trade.getPrice();
				}

				if (trade.getType().equals("sell") && newSell != 0) {
					newSell = trade.getPrice();
				}

				if (newBuy != 0 && newSell != 0) {
					break;
				}
			}

			switch (tard_type) {
			case "0":// 做多

				if (option_status.equals("2")) {
					// 平空仓
					Position position = this.getPosition(futurePostV1);
					List<Holding> holdings = position.getHolding();
					for (int i = 0; i < holdings.size(); i++) {
						Holding hold = holdings.get(i);
						if (hold.getSell_amount() > 0) {
							this.future_trade(futurePostV1, newBuy, hold.getSell_amount(), "4");// 平仓
						}
					}
					// 开仓
					double rights = okCoinUserInfo.getInfo().getBtc().getRights();
					double amount = rights * newSell / 100 * 20;
					this.future_trade(futurePostV1, newSell, amount, "1");
				} else

				if (option_status.equals("1")) {
					// 网格
					int amount = 0;
					if (newBuy - Double.parseDouble(current_tard_price) <= -Double.parseDouble(netwok_val)) {
						double rights = okCoinUserInfo.getInfo().getBtc().getRights() * 0.1;
						amount = (int) (rights * newSell / 100 * 20 * 0.1);
						this.future_trade(futurePostV1, newSell, amount, "1");
					}

					if (newBuy - Double.parseDouble(current_tard_price) >= Double.parseDouble(netwok_val)) {
						double rights = okCoinUserInfo.getInfo().getBtc().getRights() * 0.1;
						amount = (int) (rights * newSell / 100 * 20 * 0.1);
						this.future_trade(futurePostV1, newSell, amount, "3");
					}
				}
				break;
			case "1": // 做空

				// 开仓
				if (option_status.equals("2")) {
					// 平多仓
					Position position = this.getPosition(futurePostV1);
					List<Holding> holdings = position.getHolding();
					for (int i = 0; i < holdings.size(); i++) {
						Holding hold = holdings.get(i);
						if (hold.getBuy_amount() > 0) {
							this.future_trade(futurePostV1, newSell, hold.getBuy_amount(), "3");// 平仓
						}
					}
					double rights = okCoinUserInfo.getInfo().getBtc().getRights();
					double amount = rights * newSell / 100 * 20;
					this.future_trade(futurePostV1, newSell, amount, "1");
				} else

				if (option_status.equals("1")) {
					// 网格

					int amount = 0;
					if (newBuy - Double.parseDouble(current_tard_price) <= -Double.parseDouble(netwok_val)) {
						double rights = okCoinUserInfo.getInfo().getBtc().getRights() * 0.1;
						amount = (int) (rights * newSell / 100 * 20 * 0.1);
						this.future_trade(futurePostV1, newSell, amount, "4");
					}

					if (newBuy - Double.parseDouble(current_tard_price) >= Double.parseDouble(netwok_val)) {
						double rights = okCoinUserInfo.getInfo().getBtc().getRights() * 0.1;
						amount = (int) (rights * newSell / 100 * 20 * 0.1);
						this.future_trade(futurePostV1, newSell, amount, "2");
					}

				}
				break;
			case "2":// 平仓
				Position position = this.getPosition(futurePostV1);
				List<Holding> holdings = position.getHolding();
				for (int i = 0; i < holdings.size(); i++) {
					Holding hold = holdings.get(i);
					if (hold.getBuy_amount() > 0) {
						this.future_trade(futurePostV1, newSell, hold.getBuy_amount(), "3");// 平仓
					}
					if (hold.getSell_amount() > 0) {
						this.future_trade(futurePostV1, newBuy, hold.getSell_amount(), "4");// 平仓
					}
				}
				break;
			default:
				break;
			}

		} catch (Exception e) {
			
			String current_tard_price = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_tard_price");
			String option_status = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("option_status");
			String current_order_id = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("current_order_id");
			String netwok_val = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("netwok_val");
			String tard_type = PropertiesUtils.getInstance(System.getProperty("user.dir") + "/conf/redis-config.properties").getProperty("tard_type");
			
			redisUtilStr.set("netwok_val", netwok_val,0);
			redisUtilStr.set("current_tard_price", current_tard_price,0);
			redisUtilStr.set("option_status", option_status,0);
			redisUtilStr.set("current_order_id", current_order_id,0);
			redisUtilStr.set("tard_type", tard_type,0);
			e.printStackTrace();
		}

	}

	/**
	 * 期货下单 Parameters: symbol btc_usd:比特币 ltc_usd :莱特币 contractType 合约类型:
	 * this_week:当周 next_week:下周 month:当月 quarter:季度 price 价格 amount 委托数量 type
	 * 1:开多 2:开空 3:平多 4:平空 matchPrice 是否为对手价 0:不是 1:是
	 * ,当取值为1时,price无效Returns:Throws:HttpExceptionIOException
	 * 
	 * @param futurePostV1
	 * @param price
	 * @param amount
	 * @param type
	 * @throws HttpException
	 * @throws IOException
	 */
	private void future_trade(IFutureRestApi futurePostV1, double price, double amount, String type) throws HttpException, IOException {
		// 期货下单//测试
		// String tradeResultV1 = futurePostV1.future_trade("btc_usd",
		// "quarter", "" + price, "" + amount, type, "0");//
		// JSONObject tradeJSV1 = JSONObject.parseObject(tradeResultV1);//
		// String tradeOrderV1 = tradeJSV1.getString("order_id");
		System.out.println("btc_usd " + " quarter " + " price : " + price + " amount : " + amount + " type : " + type + " 0");
	}

	// 期货下单
	// String tradeResultV1 = futurePostV1.future_trade("btc_usd",
	// "quarter", "10.134", "1", "1", "0");
	// JSONObject tradeJSV1 = JSONObject.parseObject(tradeResultV1);
	// String tradeOrderV1 = tradeJSV1.getString("order_id");
	// System.out.println(tradeResultV1);
	// String userInfo = futurePostV1.future_userinfo();
	//
	// OkCoinUserInfo okCoinUserInfo =
	// JSONObject.toJavaObject(JSONObject.parseArray(userInfo),
	// OkCoinUserInfo.class);

	// // 期货用户订单查询
	// futurePostV1.future_order_info("btc_usd", "this_week",
	// tradeOrderV1, "1", "1", "2");
	//
	// // 取消订单
	// futurePostV1.future_cancel("btc_usd", "this_week", tradeOrderV1);

	private List<HisData> KLineDataToHisData(List<KLineData> klines) {

		List<HisData> hisDatas = new ArrayList<HisData>();
		for (KLineData obj : klines) {
			HisData hisData = new HisData();
			hisData.setOPEN(obj.getOpenPrice());
			hisData.setCLOSE(obj.getClosePrice());
			hisData.setHIGH(obj.getHighPrice());
			hisData.setLOW(obj.getLowPrice());
			hisData.setTIME(new Date(obj.getDate()));
			hisDatas.add(hisData);
		}

		return hisDatas;
	}

	private OkCoinUserInfo getOkCoinUserInfo(IFutureRestApi futurePostV1) throws HttpException, IOException {
		String userInfo = futurePostV1.future_userinfo();
		String userInfo4fix = futurePostV1.future_userinfo_4fix();
		OkCoinUserInfo okCoinUserInfo = new OkCoinUserInfo();

		if (JSONObject.parseObject(userInfo).getLong("error_code") == 20022) {
			List<Contracts> cs = (List<Contracts>) net.sf.json.JSONArray.toList(net.sf.json.JSONObject.fromObject(userInfo4fix).getJSONObject("info").getJSONObject("btc").getJSONArray("contracts"), Contracts.class);
			Btc btc = new Btc();
			btc.setContracts(cs);
			btc.setBalance(net.sf.json.JSONObject.fromObject(userInfo4fix).getJSONObject("info").getJSONObject("btc").getDouble("balance"));
			btc.setRights(net.sf.json.JSONObject.fromObject(userInfo4fix).getJSONObject("info").getJSONObject("btc").getDouble("rights"));
			Info info = new Info();
			info.setBtc(btc);
			okCoinUserInfo.setInfo(info);
			okCoinUserInfo.setResult(net.sf.json.JSONObject.fromObject(userInfo4fix).getBoolean("result"));

		} else {
			List<Contracts> cs = (List<Contracts>) net.sf.json.JSONArray.toList(net.sf.json.JSONObject.fromObject(userInfo).getJSONObject("info").getJSONObject("btc").getJSONArray("contracts"), Contracts.class);
			Btc btc = new Btc();
			btc.setContracts(cs);
			btc.setBalance(net.sf.json.JSONObject.fromObject(userInfo).getJSONObject("info").getJSONObject("btc").getDouble("balance"));
			btc.setRights(net.sf.json.JSONObject.fromObject(userInfo).getJSONObject("info").getJSONObject("btc").getDouble("rights"));
			Info info = new Info();
			info.setBtc(btc);
			okCoinUserInfo.setInfo(info);
			okCoinUserInfo.setResult(net.sf.json.JSONObject.fromObject(userInfo).getBoolean("result"));
		}

		return okCoinUserInfo;
	}

	private Position getPosition(IFutureRestApi futurePostV1) throws HttpException, IOException {
		String position = futurePostV1.future_position("btc_usd", "quarter");
		// 期货用户逐仓持仓查询
		String position4fix = futurePostV1.future_position_4fix("btc_usd", "quarter");

		Position positionObj = new Position();
		if (JSONObject.parseObject(position).getLong("error_code") == 20022) {
			List<Holding> holdings = (List<Holding>) net.sf.json.JSONArray.toList(net.sf.json.JSONObject.fromObject(position4fix).getJSONArray("holding"), Holding.class);
			positionObj.setHolding(holdings);
			positionObj.setResult(net.sf.json.JSONObject.fromObject(position4fix).getBoolean("result"));

		} else {
			List<Holding> holdings = (List<Holding>) net.sf.json.JSONArray.toList(net.sf.json.JSONObject.fromObject(position).getJSONArray("holding"), Holding.class);
			positionObj.setHolding(holdings);
			positionObj.setResult(net.sf.json.JSONObject.fromObject(position).getBoolean("result"));

		}

		return positionObj;

	}
	
	
	public static void main(String[] args) {

		FutureNo1TradingService futureNo1Service = new FutureNo1TradingService();
		
		ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

		service.scheduleAtFixedRate(futureNo1Service, 0, 3, TimeUnit.SECONDS);
	}
}
